package com.swak.frame.api.filter.interceptor;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;

import org.apache.commons.collections4.CollectionUtils;

import com.swak.frame.filter.SwakMethodAnnotationParser;
import com.swak.frame.filter.annotation.ApiFilterOperation;
import com.swak.frame.interceptor.AbstractBasicOperationSource;

public class DefaultApiFilterOperationSource extends AbstractBasicOperationSource<ApiFilterOperation> implements ApiFilterOperationSource {

	private static final Collection<ApiFilterOperation> NULL_ATTRIBUTE = Collections.emptyList();

	private SwakMethodAnnotationParser annotationParser;
	
	@Override
	public Collection<ApiFilterOperation> getBasicOperations(Method method, Class<?> targetClass) {
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}
		Object cacheKey = getCacheKey(method, targetClass);
		Collection<ApiFilterOperation> cached = this.attributeCache.get(cacheKey);
		if (cached != null) {
			return (cached != NULL_ATTRIBUTE ? cached : null);
		} else {
			Collection<ApiFilterOperation> operations = computeOperations(method, targetClass);
			if (CollectionUtils.isNotEmpty(operations)) {
				logger.trace("Adding @SwakMethod method '" + method.getName() + "' with attribute: " + operations);
				this.attributeCache.put(cacheKey, operations);
			} else {
				this.attributeCache.put(cacheKey, NULL_ATTRIBUTE);
			}
			return operations;
		}
	}

	@Override
	protected Collection<ApiFilterOperation> findAnnotationOperations(Class<?> clazz) {
		return annotationParser.parseAnnotations(clazz);
	}

	@Override
	protected Collection<ApiFilterOperation> findAnnotationOperations(Method method,Class<?>  targetClass) {
		return annotationParser.parseAnnotations(method,targetClass);
	}
	
	@Override
	public void afterSingletonsInstantiated() {
		//igroe
	}

	public void setAnnotationParser(SwakMethodAnnotationParser annotationParser) {
		this.annotationParser = annotationParser;
	}

}
